home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / (A)Z / (A)Z8.ADF / WBLander / rocket.c < prev    next >
C/C++ Source or Header  |  1989-06-27  |  13KB  |  636 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <intuition/intuition.h>
  4. #include <graphics/sprite.h>
  5. #include <hardware/custom.h>
  6. #include <stdio.h> 
  7. #include <ctype.h> 
  8.  
  9. #define INTUITION_REV 1 
  10. #define GRAPHICS_REV  1 
  11.  
  12. #define SAUCERSPEED 200
  13. #define SAUCERDELAY 200
  14. #define ROCKETHEIGHT 16
  15. #define SPRWIDTH 32
  16. #define PIXRATIO 2
  17. #define SCALEFACTOR 100
  18. #define XMAX (640*SCALEFACTOR)
  19. #define YMAX (200*SCALEFACTOR)
  20. #define XMIN (-(SPRWIDTH/PIXRATIO)*SCALEFACTOR)
  21. #define YMIN (-ROCKETHEIGHT*SCALEFACTOR)
  22.  
  23. #define OK 0
  24. #define LANDED 1
  25. #define CRASHEDGOOD 2
  26. #define CRASHEDBAD 3
  27. #define CRASHEDSAUCER 4
  28.  
  29. USHORT rocket_image[ROCKETHEIGHT*2] = {
  30.     0x0000, 0x0000,
  31.     0x0000, 0x0000,
  32.     0x0100, 0x0100,
  33.     0x0100, 0x0100,
  34.     0x0380, 0x0380,
  35.     0x0380, 0x0380,
  36.     0x07c0, 0x07c0,
  37.     0x07c0, 0x07c0,
  38.     0x0fe0, 0x0fe0,
  39.     0x0fe0, 0x0fe0,
  40.     0x0820, 0x0820,
  41.     0x0820, 0x0820,
  42.     0x0820, 0x0820,
  43.     0x0000, 0x0000,
  44.     0x0000, 0x0000,
  45.     0x0000, 0x0000,
  46. };
  47. USHORT flame[3][ROCKETHEIGHT*2] = {
  48. {
  49.     0x0000, 0x0000,
  50.     0x0000, 0x0000,
  51.     0x0100, 0x0100,
  52.     0x0100, 0x0100,
  53.     0x0380, 0x0380,
  54.     0x0380, 0x0380,
  55.     0x07c0, 0x07c0,
  56.     0x0fc0, 0x37c0,
  57.     0x0fe0, 0x0fe0,
  58.     0x0fe0, 0x0fe0,
  59.     0x0820, 0x0820,
  60.     0x0820, 0x0820,
  61.     0x0820, 0x0820,
  62.     0x0000, 0x0000,
  63.     0x0000, 0x0000,
  64.     0x0000, 0x0000,
  65. },
  66. {
  67.     0x0000, 0x0000,
  68.     0x0000, 0x0000,
  69.     0x0100, 0x0100,
  70.     0x0100, 0x0100,
  71.     0x0380, 0x0380,
  72.     0x0380, 0x0380,
  73.     0x07c0, 0x07c0,
  74.     0x07e0, 0x07d8,
  75.     0x0fe0, 0x0fe0,
  76.     0x0fe0, 0x0fe0,
  77.     0x0820, 0x0820,
  78.     0x0820, 0x0820,
  79.     0x0820, 0x0820,
  80.     0x0000, 0x0000,
  81.     0x0000, 0x0000,
  82.     0x0000, 0x0000,
  83. },
  84. {
  85.     0x0000, 0x0000,
  86.     0x0000, 0x0000,
  87.     0x0100, 0x0100,
  88.     0x0100, 0x0100,
  89.     0x0380, 0x0380,
  90.     0x0380, 0x0380,
  91.     0x07c0, 0x07c0,
  92.     0x07c0, 0x07c0,
  93.     0x0fe0, 0x0fe0,
  94.     0x0fe0, 0x0fe0,
  95.     0x0ba0, 0x0c60,
  96.     0x0920, 0x0ee0,
  97.     0x0920, 0x0aa0,
  98.     0x0000, 0x0380,
  99.     0x0000, 0x0100,
  100.     0x0000, 0x0100,
  101. }
  102. };
  103. USHORT sprite_colors[3] = { 0x0f95, 0x0d44, 0x0fff };
  104. #define SAUCERHEIGHT 5
  105. USHORT saucer_image[3][SAUCERHEIGHT*2] = {
  106. {
  107.     0x0ff0, 0x0ff0,
  108.     0xffff, 0xffff,
  109.     0xb6db, 0x6db6,
  110.     0xffff, 0xffff,
  111.     0x0ff0, 0x0ff0
  112. },
  113. {
  114.     0x0ff0, 0x0ff0,
  115.     0xffff, 0xffff,
  116.     0x6db6, 0xdb6d,
  117.     0xffff, 0xffff,
  118.     0x0ff0, 0x0ff0
  119. },
  120. {
  121.     0x0ff0, 0x0ff0,
  122.     0xffff, 0xffff,
  123.     0xdb6d, 0xb6db,
  124.     0xffff, 0xffff,
  125.     0x0ff0, 0x0ff0
  126. }
  127. };
  128.  
  129. UWORD *rbuf, *sbuf;
  130. struct SimpleSprite rocket, saucer;
  131. int rocket_sprite, saucer_sprite;
  132. struct Window *window, *badwindow;
  133. struct ViewPort *viewport;
  134. struct Remember *Memory;
  135.  
  136. /*   Intuition always wants to see these declarations */
  137. struct IntuitionBase *IntuitionBase;
  138. struct GfxBase *GfxBase;
  139.  
  140. /* my window structure */
  141. struct NewWindow NewWindow = {
  142.     160,  50, 
  143.     240,  10, 
  144.     0,    1, 
  145.     INTUITICKS | CLOSEWINDOW | RAWKEY | ACTIVEWINDOW | INACTIVEWINDOW,
  146.     WINDOWCLOSE | SMART_REFRESH | ACTIVATE | WINDOWDRAG | WINDOWDEPTH,
  147.     NULL, 
  148.     NULL, 
  149.     "Workbench Lander", 
  150.     NULL, 
  151.     NULL, 
  152.     0, 0, 
  153.     0, 0, 
  154.     WBENCHSCREEN, 
  155. };
  156.  
  157. struct NewWindow BadWindow = {
  158.     160, 11,
  159.     240, 10,
  160.     0, 1,
  161.     ACTIVEWINDOW | INACTIVEWINDOW | CLOSEWINDOW,
  162.     WINDOWCLOSE | SMART_REFRESH | WINDOWDRAG | WINDOWDEPTH,
  163.     NULL,
  164.     NULL,
  165.     "Don't land here...",
  166.     NULL,
  167.     NULL,
  168.     0, 0,
  169.     0, 0,
  170.     WBENCHSCREEN,
  171. };
  172. struct IntuiMessage *NewMessage;
  173.  
  174. /******************************************************/
  175. /*                   Main Program                     */
  176. /*                                                    */
  177. /*      This is the main body of the program.         */
  178. /******************************************************/
  179.  
  180. int x, y, vx, vy, ax, ay;
  181. int buttons = 0;
  182.  
  183. char *cycle[] = {
  184.     "Workbench Lander",
  185.     "Use cursor keys to",
  186.     "Land on this window",
  187.     "Workbench Lander",
  188.     "Don't hit too hard",
  189.     "Workbench Lander",
  190.     "Don't fall over",
  191.     "Workbench Lander",
  192.     "Don't get caught",
  193.     "Workbench Lander",
  194.     "Space is big",
  195.     "Space is dark",
  196.     "It's hard to find",
  197.     "A place to park",
  198.     "BURMA SHAVE",
  199.     "Workbench Lander",
  200.     "Another fine hack",
  201.     "by Peter da Silva",
  202.     0
  203. };
  204.  
  205. addflame(n)
  206. int n;
  207. {
  208.     buttons |= n;
  209.     recalc_rocket();
  210. }
  211.  
  212. delflame(n)
  213. int n;
  214. {
  215.     buttons &= ~n;
  216.     recalc_rocket();
  217. }
  218.  
  219. recalc_rocket()
  220. {
  221.     int b, i;
  222.     rbuf[0] = rbuf[1] = 0;
  223.     for(i = 0; i < 2*ROCKETHEIGHT; i++)
  224.         rbuf[i+2] = rocket_image[i];
  225.     rbuf[2*ROCKETHEIGHT+2] = 0;
  226.     rbuf[2*ROCKETHEIGHT+3] = 0;
  227.  
  228.     for(b = 0; b < 3; b++)
  229.         if(buttons & (1<<b))
  230.             for(i = 0; i < 2*ROCKETHEIGHT; i++)
  231.                 rbuf[i+2] |= flame[b][i];
  232.  
  233.     ChangeSprite(viewport, &rocket, rbuf);
  234. }
  235.  
  236. set_saucer(n)
  237. int n;
  238. {
  239.     int i;
  240.  
  241.     sbuf[0] = sbuf[1] = 0;
  242.     for(i = 0; i < 2*SAUCERHEIGHT; i++)
  243.         sbuf[i+2] = saucer_image[n][i];
  244.     sbuf[2*SAUCERHEIGHT+2] = 0;
  245.     sbuf[2*SAUCERHEIGHT+3] = 0;
  246.  
  247.     ChangeSprite(viewport, &saucer, sbuf);
  248. }
  249.  
  250. #define BEGIN_EXPLOSION 0
  251. #define IN_EXPLOSION 1
  252. #define END_EXPLOSION 2
  253. int exploding;
  254. int coloregs;
  255. int counter;
  256.  
  257. int KeepGoing;
  258. int timeout;
  259. int cycle_position, cycle_timeout;
  260. int saucer_timeout, saucer_x, saucer_y, saucer_cycle, saucer_up;
  261.  
  262. explode()
  263. {
  264.     int i;
  265.     if(!exploding) {
  266.         counter = 21;
  267.         exploding = 1;
  268.     }
  269.     if(counter-- < 0) {
  270.         exploding = 0;
  271.         x = y = 200;
  272.         vx = 100;
  273.         vy = 0;
  274.         ax = 0;
  275.         ay = 10;
  276.         saucer_timeout = SAUCERDELAY;
  277.         timeout = 10;
  278.         for(i = 0; i < 3; i++)
  279.             SetRGB4(viewport, coloregs+1+i,
  280.                 sprite_colors[i]&0x000F,
  281.                 (sprite_colors[i]&0x00F0)>>4,
  282.                 (sprite_colors[i]&0x0F00)>>8);
  283.     } else {
  284.         for(i = 0; i < 3; i++)
  285.             SetRGB4(viewport, coloregs+1+i,
  286.                 RangeRand(16),
  287.                 RangeRand(16),
  288.                 RangeRand(16));
  289.     }
  290. }
  291.  
  292. main()
  293. {
  294.     int i;
  295.  
  296.     Memory = NULL;
  297.  
  298.     IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", INTUITION_REV);
  299.     if( IntuitionBase == NULL )
  300.     {
  301.         puts("can't open intuition\n");
  302.         cleanup_and_exit(50);
  303.     }
  304.  
  305.     GfxBase = (struct GfxBase *)OpenLibrary("graphics.library",GRAPHICS_REV);
  306.     if( GfxBase == NULL )
  307.     {
  308.         puts("can't open graphics library\n");
  309.         cleanup_and_exit(50);
  310.     }
  311.  
  312.     if(( window = (struct Window *)OpenWindow(&NewWindow) ) == NULL)
  313.     {
  314.         puts("can't open window\n");
  315.         cleanup_and_exit(50);
  316.     }
  317.  
  318.     if(( badwindow = (struct Window *)OpenWindow(&BadWindow) ) == NULL)
  319.     {
  320.         puts("can't open obstacle\n");
  321.         cleanup_and_exit(50);
  322.     }
  323.  
  324.     viewport = ViewPortAddress(window);
  325.  
  326.     if((rocket_sprite = GetSprite(&rocket, 2)) == -1)
  327.         if((rocket_sprite = GetSprite(&rocket, 4)) == -1)
  328.         if((rocket_sprite = GetSprite(&rocket, 6)) == -1) {
  329.             puts("can't get rocket_sprite\n");
  330.             cleanup_and_exit(50);
  331.         }
  332.     if((saucer_sprite = GetSprite(&saucer, rocket_sprite+1)) == -1) {
  333.         puts("can't get saucer_sprite\n");
  334.         cleanup_and_exit(50);
  335.     }
  336.     rocket.x = 0;
  337.     rocket.y = 0;
  338.     rocket.height = ROCKETHEIGHT;
  339.     saucer.x = 0;
  340.     saucer.y = 0;
  341.     saucer.height = SAUCERHEIGHT;
  342.  
  343.     coloregs = ((rocket_sprite & 0x06)*2)+16;
  344.  
  345.     for(i = 0; i < 3; i++)
  346.         SetRGB4(viewport, coloregs+1+i,
  347.             sprite_colors[i]&0x000F,
  348.             (sprite_colors[i]&0x00F0)>>4,
  349.             (sprite_colors[i]&0x0F00)>>8);
  350.  
  351.     if(!(rbuf = AllocRemember(&Memory, 4L * ROCKETHEIGHT + 8L, MEMF_CHIP)))
  352.         cleanup_and_exit(50);
  353.  
  354.     if(!(sbuf = AllocRemember(&Memory, 4L * SAUCERHEIGHT + 8L, MEMF_CHIP)))
  355.         cleanup_and_exit(50);
  356.  
  357.     buttons = 0;
  358.     recalc_rocket();
  359.     set_saucer(0);
  360.  
  361.     KeepGoing = TRUE;
  362.  
  363.     timeout = 0;
  364.     cycle_timeout = 10;
  365.     cycle_position = 0;
  366.  
  367.     saucer_timeout = SAUCERDELAY;
  368.     saucer_up = 0;
  369.     MoveSprite(viewport, &saucer, -20, -20);
  370.  
  371.     SetWindowTitles(window, -1, "Workbench Lander (C) 1987 by Peter da Silva");
  372.     x = y = 200;
  373.     vx = 100;
  374.     vy = 0;
  375.     ax = 0;
  376.     ay = 10;
  377.     MoveSprite(viewport, &rocket, x/SCALEFACTOR, y/SCALEFACTOR);
  378.  
  379.     while( KeepGoing )
  380.     {
  381.         Wait((1 << window->UserPort->mp_SigBit) |
  382.              (1 << badwindow->UserPort->mp_SigBit));
  383.         WaitTOF();
  384.  
  385.         while( NewMessage=(struct IntuiMessage *)GetMsg(badwindow->UserPort) )
  386.         {
  387.             ReplyMsg( NewMessage );
  388.             switch( NewMessage->Class )
  389.             {
  390.             case CLOSEWINDOW:
  391.                 KeepGoing = FALSE;
  392.                 break;
  393.             case ACTIVEWINDOW:
  394.                 SetWindowTitles(badwindow, "...or click here", -1);
  395.                 break;
  396.             case INACTIVEWINDOW:
  397.                 SetWindowTitles(badwindow, BadWindow.Title, -1);
  398.                 break;
  399.             }
  400.         }
  401.  
  402.         while( NewMessage=(struct IntuiMessage *)GetMsg(window->UserPort) )
  403.         {
  404.             ReplyMsg( NewMessage );
  405.             switch( NewMessage->Class )
  406.             {
  407.             case CLOSEWINDOW:
  408.                 KeepGoing = FALSE;
  409.                 break;
  410.             case RAWKEY:
  411.                 switch(NewMessage -> Code) {
  412.                     case 0x4C:
  413.                         addflame(4);
  414.                         ay = -40; 
  415.                         break;
  416.                     case 0x4C|0x80:
  417.                         delflame(4);
  418.                         ay = 10; 
  419.                         break;
  420.                     case 0x4E:
  421.                         addflame(1);
  422.                         ax = 10;
  423.                         break;
  424.                     case 0x4F|0x80:
  425.                         delflame(3);
  426.                         ax = 0;
  427.                         break;
  428.                     case 0x4E|0x80:
  429.                         delflame(3);
  430.                         ax = 0;
  431.                         break;
  432.                     case 0x4F:
  433.                         addflame(2);
  434.                         ax = -10;
  435.                         break;
  436.                 }
  437.                 break;
  438.             case ACTIVEWINDOW:
  439.                 SetWindowTitles(window, cycle[cycle_position], -1);
  440.                 break;
  441.             case INACTIVEWINDOW:
  442.                 SetWindowTitles(window, "Click me", -1);
  443.                 break;
  444.             case INTUITICKS:
  445.                 if(exploding) {
  446.                     explode();
  447.                     break;
  448.                 }
  449.                 if(timeout > 0) {
  450.                     timeout--;
  451.                     if(timeout == 0) {
  452.                         SetWindowTitles(badwindow, BadWindow.Title, -1);
  453.                         SetWindowTitles(window, cycle[cycle_position], -1);
  454.                         cycle_timeout = 10;
  455.                     }
  456.                 } else if(timeout == 0) {
  457.                     cycle_timeout--;
  458.                     if(cycle_timeout <= 0) {
  459.                         cycle_timeout = 10;
  460.                         cycle_position++;
  461.                         if(cycle[cycle_position]==0)
  462.                             cycle_position = 0;
  463.                         SetWindowTitles(window, cycle[cycle_position], -1);
  464.                     }
  465.                 }
  466.                 if(saucer_timeout == 0) {
  467.                     int dx, dy;
  468.                     if(saucer_up == 0) {
  469.                         saucer_up = 1;
  470.                         saucer_x = 200;
  471.                         saucer_y = 200;
  472.                         saucer_cycle = 0;
  473.                     }
  474.                     set_saucer(saucer_cycle++);
  475.                     if(saucer_cycle >= 3)
  476.                         saucer_cycle = 0;
  477.                     dx = dy = 0;
  478.                     if(saucer_x < x-SAUCERSPEED)
  479.                         dx = SAUCERSPEED;
  480.                     else if(saucer_x > x+SAUCERSPEED)
  481.                         dx = -SAUCERSPEED;
  482.                     if(saucer_y < y-SAUCERSPEED)
  483.                         dy = SAUCERSPEED;
  484.                     else if(saucer_y > y+SAUCERSPEED)
  485.                         dy = -SAUCERSPEED;
  486.                     if(dy == 0) dx += dx/2;
  487.                     if(dx == 0) dy += dy/2;
  488.                     saucer_x += dx;
  489.                     saucer_y += dy;
  490.                     MoveSprite(viewport, &saucer,
  491.                         saucer_x/SCALEFACTOR, saucer_y/SCALEFACTOR);
  492.                 } else  {
  493.                     if(saucer_timeout != -1)
  494.                         saucer_timeout--;
  495.                     if(saucer_up) {
  496.                         saucer_up = 0;
  497.                         MoveSprite(viewport, &saucer, -20, -20);
  498.                     }
  499.                 }
  500.  
  501.                 x += vx;
  502.                 y += vy;
  503.                 vx += ax;
  504.                 vy += ay;
  505.  
  506.                 if(x > XMAX) x = XMIN;
  507.                 if(x < XMIN) x = XMAX;
  508.                 if(y < YMIN) y = YMAX;
  509.                 if(y > YMAX) y = YMIN;
  510.  
  511.                 switch(HitWindow()) {
  512.                     case OK:
  513.                         if(ay==0) {
  514.                             ay = 10;
  515.                             timeout = 10;
  516.                             saucer_timeout = SAUCERDELAY;
  517.                         }
  518.                         break;
  519.                     case LANDED:
  520.                         if(vy >= -2*SCALEFACTOR && vy < 0) {
  521.                             timeout = 10;
  522.                             saucer_timeout = SAUCERDELAY;
  523.                             break;
  524.                         }
  525.                            if(vy >= 0 && vy <= SCALEFACTOR &&
  526.                            vx >= -20 && vx <= 20) {
  527.                             if(timeout >= 0) {
  528.                                 if(vy <= 30 && vx == 0)
  529.                                     SetWindowTitles(window, "Great Landing!", -1);
  530.                                 else if(vy <= 70 && vx == 0)
  531.                                     SetWindowTitles(window, "Good Landing.", -1);
  532.                                 else
  533.                                     SetWindowTitles(window, "Just made it...", -1);
  534.                             }
  535.                             timeout = -1;
  536.                             vx = vy = 0;
  537.                             ax = ay = 0;
  538.                             saucer_timeout = -1;
  539.                             break;
  540.                         }
  541.                     case CRASHEDGOOD:
  542.                         SetWindowTitles(window, "OUCH! That hurt!", -1);
  543.                         explode();
  544.                         break;
  545.                     case CRASHEDBAD:
  546.                         SetWindowTitles(badwindow, "OUCH! That hurt!", -1);
  547.                         explode();
  548.                         break;
  549.                     case CRASHEDSAUCER:
  550.                         SetWindowTitles(window, "GOTCHA!", -1);
  551.                         explode();
  552.                         break;
  553.                 }
  554.                 MoveSprite(viewport, &rocket,
  555.                     x/SCALEFACTOR, y/SCALEFACTOR);
  556.                 break;
  557.             }   /* end of switch (class) */
  558.         }   /* end of while ( newmessage )*/
  559.     }  /* end while ( keepgoing ) */
  560.     cleanup_and_exit(0);
  561. } /* end of main */
  562.  
  563. cleanup_and_exit(flag)
  564. {
  565.     if(saucer_sprite > 0)
  566.         FreeSprite(saucer_sprite);
  567.     if(rocket_sprite > 0)
  568.         FreeSprite(rocket_sprite);
  569.     FreeRemember(&Memory, TRUE);
  570.     if(badwindow)
  571.         CloseWindow(badwindow);
  572.     if(window)
  573.         CloseWindow(window);
  574.     if(GfxBase)
  575.         CloseLibrary(GfxBase);
  576.     if(IntuitionBase)
  577.         CloseLibrary(IntuitionBase);
  578.     exit(flag);
  579. }
  580.  
  581. HitWindow()
  582. {
  583.     int sx = x/SCALEFACTOR;
  584.     int sy = y/SCALEFACTOR;
  585.     int ret;
  586.  
  587.     ret = checkwindow(sx, sy, window, 1);
  588.     if(!ret)
  589.         ret = checkwindow(sx, sy, badwindow, 0);
  590.     if(!ret)
  591.         ret = checksaucer();
  592.     return ret;
  593. }
  594.  
  595. checkwindow(sx, sy, window, canland)
  596. int sx, sy;
  597. struct Window *window;
  598. int canland;
  599. {
  600.     int top = window->TopEdge-ROCKETHEIGHT+3;
  601.     int bottom = window->TopEdge+window->Height - 2;
  602.     int left = window->LeftEdge-SPRWIDTH+4*PIXRATIO;
  603.     int right = window->LeftEdge+window->Width-5*PIXRATIO;
  604.  
  605.     if(sx<left || sx>right) return OK;
  606.     if(sy>bottom || sy<top) return OK;
  607.     if(canland) {
  608.         if(sy>top+3) return CRASHEDGOOD;
  609.         if(sx<left+7*PIXRATIO || sx>right-7*PIXRATIO) return CRASHEDGOOD;
  610.         return LANDED;
  611.     } else {
  612.         return CRASHEDBAD;
  613.     }
  614. }
  615.  
  616. checksaucer()
  617. {
  618.     int sx, sy, rx, ry, top, bottom, left, right;
  619.  
  620.     if(!saucer_up) return OK;
  621.  
  622.     rx = x/SCALEFACTOR;
  623.     ry = y/SCALEFACTOR;
  624.     sx = saucer_x/SCALEFACTOR;
  625.     sy = saucer_y/SCALEFACTOR;
  626.  
  627.     top = sy-ROCKETHEIGHT+3;
  628.     bottom = sy+SAUCERHEIGHT - 2;
  629.     left = sx-SPRWIDTH+4*PIXRATIO;
  630.     right = sx+SPRWIDTH-5*PIXRATIO;
  631.  
  632.     if(rx<left || rx>right) return OK;
  633.     if(ry>bottom || ry<top) return OK;
  634.     return CRASHEDSAUCER;
  635. }
  636.